<html xmlns="http://www.w3.org/1999/xhtml" id="program-development"
      xmlns:d="docbook">

<head>
<title>Program Development</title>
</head>
<body>

<h1>Overview of Laszlo Application Development</h1>
<p>
This chapter summarizes information about Laszlo application structure and mechanics that an experienced programmer will need in order to start playing with code.</p>

<p>This discussion is necessarily abbreviated and incomplete; its
purpose is merely to point you in the right direction. As you begin to
write LZX applications, you should also work through the <a
href="${tutorials}">tutorials</a>.</p>

<h2>The program development cycle in a nutshell</h2>
<note>
The program development cycle differs somewhat depending on whether you deploy your application proxied or serverless. 
Developing proxied applications is the simpler case, so we'll start with that here.  
</note>

<p>
The process of developing a Laszlo application can be summarized:</p>
<ol>
<li>
start up the Laszlo Presentation Server</li>
<li>
using a text editor, write program code; save the file with a .lzx extension</li>
<li>
place file in an appropriate directory</li>
<li>
load the application into a web browser</li>
<li>
debug and modify the program</li>
<li>
repeat steps 2-5 until the program is perfect</li>
<li>
optionally, optimize startup time using the KRANK feature</li>
<li>
deploy the application</li>
</ol>
<p>
Each of these steps is described in turn below.</p>

<h3>Start up the Laszlo Presentation Server</h3>

<p>
The way to start the Laszlo Presentation Server (LPS) depends on the operating system and how it was installed. On Windows, typically you start LPS from the Start menu; on Mac OS X the default installation places the LPS launch icon on your desktop. If you don't have LPS installed on your machine, you can download it from http://www.laszlosystems.com/developers/</p>


<h3>Create a program file</h3>

<p>Because LZX files are XML documents, you can use any text or XML
editor to create and edit source. Filenames must end with the .lzx
extension. As you write, you'll want to have the <a
href="${reference}">LZX Reference Manual</a> handy. See below for a
discussion of how to use this document efficiently.</p>

<h3><a name="where-to-put-files"></a>
Place file in the appropriate directory</h3>

<p>In order to be compiled by the Laszlo Presentation Server, files
must be placed in subdirectories of the following path:</p>

<p>[Windows]</p>
<pre>c:\Program Files\Laszlo Presentation Server @VERSIONID@\jakarta-tomcat-5.0.24\webapps\lps-@VERSIONID@\</pre>

<p>[MacOS]</p>
<pre>Macintosh HD:/Applications/Laszlo Presentation Server @VERSIONID@/jakarta-tomcat-5.0.24/webapps/lps-@VERSIONID@:</pre>

<p>Typically you will create a directory with a name such as
<code>my-apps</code> in which to place programs under development. You
can nest subdirectories, such as</p>

<pre>my-apps/practice/samples</pre>

<p>so long as they are under the correct path to LPS.</p>


<h3>Load the application into a web browser</h3>

<p>
In order to run your program, simply load it into your browser. The exact URL depends on the configuration of the server, but will typically look something like:</p>

<pre>http://localhost:8080/lps-@VERSIONID@/<i>path to your directory</i></pre>

<p>The LPS checks the source files for valid syntax, compiles them,
caches the executables and makes the application immediately visible
in the browser:</p>

<img src="images/browser.png" class="screenshot"/>


<h3>Debug and modify the program</h3>

<p>
If the Laszlo Presentation Server detects errors that prevent compilation, error messages are displayed in the browser:</p>

<img src="images/compilation-errors.png" class="screenshot"/>

<p>If it detects non-critical errors or questionable constructs that do not prevent compilation, warning messages are displayed in the browser below the application (you may have to scroll down to see them):</p>

<img src="images/compilation-warnings.png" class="screenshot"/>

<p>Runtime errors are displayed in the debugger, if the debugger is running.</p>

<p>See <xref linkend="program-development.debugging"/> for a brief discussion of the debugger.  See <xref linkend="debugging"/> for a full dicussion.</p>

<h3>Iterate</h3>

<p>
After you've made changes to the source, simply click the Refresh button on the browser. LPS automatically rechecks the source for syntax, then recompiles, re-caches and makes the application visible in the browser.</p>

<h3>Optimize</h3>
<p>Optimize your program using the techniques in <xref linkend="performance-tuning"/> and, if necessary, the KRANK feature.  The KRANK feature is described in .<xref linkend="krank"/>.</p>

<todo>put in short krank description here</todo>

<h3>Deploy</h3>

<p>
See <xref linkend="deployers-guide">Deploying Laszlo Applications</xref> for discussion of how to make your application available for general use.</p>

<h2>From "Hello, World" to real programs</h2>

<p>The canonical "Hello, World" program can be written in LZX:</p>

<example title="Hello, world">
&lt;canvas height="40"&gt; 
  &lt;text&gt;Hello, World!&lt;/text&gt; 
&lt;/canvas&gt; 
</example>

<p>This program illustrates three essential features of all Laszlo
applications:</p>

<ul>
  <li>LZX files are well-formed XML documents</li>
  <li><tagname>canvas</tagname> is the root node; programs open with
  the <code>&lt;canvas&gt;</code> tag and close with
  <code>&lt;/canvas&gt;</code></li>
  <li>Within the canvas, views are displayed. As we shall see, a
  <tagname>text</tagname> element is simply a kind of view.</li>
</ul>

<p>The next section discusses the ingredients of a typical Laszlo
application. See also the <a href="${examples}">example programs</a>,
and the user-contributed programs at <a
href="http://www.mylaszlo.com">http://www.mylaszlo.com</a>, to get a
feel for the general structure of LZX applications.</p>

<h3>Essential Structures</h3>

<p>
Typical Laszlo applications contain the following parts, which are discussed briefly in turn below</p>
<ul>
<li>canvas (<xref linkend="program-development.canvas"/>)</li>
<li>views (<xref linkend="program-development.views"/>)</li>
<li>data (<xref linkend="program-development.data-binding"/>)</li>
<li>libraries and includes (<xref linkend="program-development.libraries-and-includes"/>)</li>
<li>comments (<xref linkend="program-development.comments"/>)</li>
</ul>


<h3 id="program-development.canvas">The Canvas</h3>

<p>
The root node of every Laszlo application is the
<glossterm>canvas</glossterm>; there is one and only one canvas per
LZX application.  The canvas is the logical container of all other
nodes in the program; visually it is a rectangle that is displayed in
the content area of a web browser. You can explicitly set the height
and width of the canvas, in pixels, by assigning values to attributes
in the opening tag:</p>

<example executable="false" title="invisible canvas">
&lt;canvas height="20" width="30&gt; 
&lt;/canvas&gt;
</example>

<p>
If you do not set the height and width, the canvas &#x2014; like other views &#x2014; sizes itself to the size of the views it contains. Unlike other views, the canvas, by default, has a nonzero width (500 pixels) and height (400 pixels). Therefore the null LZX application</p>

<example executable="false" title="null program">
&lt;canvas/&gt;
</example>

<p>defines a visual object that has a width of 600 pixels and a height
of 400 pixels.</p>

<p>In addition to its height and width, the canvas has several other
visible attributes. The background color, defined by the
<attribute>bgcolor</attribute> attribute, is most useful for learning
about the visual structures of LZX applications.</p>

<p>Consider the following application.</p>

<example title="Apparent vs. real size of the canvas">
&lt;canvas bgcolor="red"/&gt;
</example>

<p>
If you were to run this application in a separate browser you would see that the entire screen was red. As explained above, the canvas specified by this code has a height of 600 and width of 400 pixels, yet the background color fills the entire browser window, which is much larger than that. The resolution of this paradox is that by default LZX applications are served within an HTML wrapper with the same background color, and has made some assumptions about the relationship between the canvas's background color and the browser's.   Keep in mind that the canvas's actual dimensions may not correspond to the dimensions implied by the background color.</p>

<h4>The <tagname>script</tagname> tag</h4>

<p>Within LZX applications, you can embed arbitrary Javascript
functions by nesting them in <tagname>script</tagname>
constructs. This is helpful for defining (global) functions that will
be used by different classes. The <tagname>script</tagname> tag must
be a child of <tagname>canvas</tagname>.  That is to say,</p>

<example executable="false" title="&lt;script&gt; tag at canvas level">
&lt;canvas&gt;
  &lt;script&gt;
    var Constant = 1;
  &lt;/script&gt; 
&lt;/canvas&gt;
</example>

<p>is an allowed structure while</p>

<example executable="false" title="&lt;script&gt; tag not allowed inside &lt;view&gt;">
&lt;canvas&gt; 
  &lt;view&gt; 
    &lt;script&gt; <co><p>
        Wrong! The <tagname>script</tagname> tag is not allowed inside a view!</p></co>
      var Constant = 1;
    &lt;/script&gt; 
  &lt;/view&gt; 
&lt;/canvas&gt;
</example>
<p>is illegal.  </p> 
 

<h4><attribute>name</attribute> vs. <attribute>id</attribute></h4>

<p>In LZX the <attribute>id</attribute> attribute of an object is a
global identifier that is visible throughout the entire program space,
while the <attribute>name</attribute> of an object is an attribute
like any other, which can only be referenced by its path (except in
the case of named children of the canvas, as noted
below). Consider</p>

<example executable="false" title="names and IDs">
&lt;canvas&gt; 
  &lt;view id="v1" name="outer_view"&gt; 
    &lt;view id="v2" name="inner_view" bgcolor="blue"/&gt; 
  &lt;/view&gt; 
&lt;/canvas&gt;</example>

<p>The value of the outer view's background color can be referenced as
<code>v1.bgcolor</code> or <code>outer_view.bgcolor</code>. The
background color of the inner view can be referenced as
<code>v2.bgcolor</code> from anywhere within the application. To
reference it by name from outside of <varname>inner_view</varname> you would
specify <code>outer_view.inside_view.bgcolor</code>.</p>

<h4>Named children of the canvas</h4>

<p>
Objects that are named children of the canvas can be simply addressed. For example, consider</p>

<example executable="false" title="addressing named children of the canvas">
&lt;canvas&gt;
  &lt;view name="artichoke"&gt;
  &lt;!-- more program code --&gt;
&lt;/canvas&gt;</example>

<p>The view <varname>artichoke</varname> can be referenced from
anywhere within the application simply as <code>artichoke</code>. That
is, it is not necessary to reference it as
<code>canvas.artichoke</code>.</p>

<h3 id="program-development.views">Views</h3>

<p>The view is the basic visible element in a Laszlo
application. Anything that is displayed on the canvas is a view (or an
object that is an instance of a class that extends view).</p>

<h4>Visible and invisible views </h4>

<p>A view is only visible if it has color, or text, or an image
assigned to it, and if the height and width of the view are greater
than zero. For example, the following code would display only two
images even though four views are defined.  The second and third views
exist but they are completely invisible. The second has no color
assigned to it and the third has zero height. They still, however,
effect the arrangement of the other two views.</p>

<example title="nested views">
&lt;canvas height="100"&gt; 
  &lt;!-- shows a red square: --&gt; 
  &lt;view width="50" height="50" bgcolor="red"/&gt;
  &lt;!-- nothing is displayed, but view still exists: --&gt; 
  &lt;view width="50" height="50"/&gt;
  &lt;!-- nothing is displayed, but view still exists: --&gt; 
  &lt;view width="0" height="50" bgcolor="blue"/&gt;
  &lt;simplelayout axis='x' spacing="5"/&gt; 
&lt;/canvas&gt; </example>

<h4>Views as containers of other views</h4>

<p>
Views can also contain other views, allowing you to create complex visual elements. Each 'parent' view can have any number of children. By default, each child view is positioned relative to the top-left corner of its parent as shown in the example.</p>

<p>Although it is always possible to position any view by specifying
its horizontal (<attribute>x</attribute>) and vertical
(<attribute>y</attribute>) origin, stated in pixels, relative to its
parent, it is often convenient to have the system lay things out for
you. Layout types built into the system include
<tagname>simplelayout</tagname>, <tagname>stableborderlayout</tagname>,
<tagname>constantlayout</tagname>, <tagname>resizelayout</tagname> and
<tagname>wrappinglayout</tagname>.</p>

<h4>View sizing and clipping</h4>

<p>Consider the following application:</p>

<example title="Parent and children dimensions">
&lt;canvas height="200"&gt; 
  &lt;view bgcolor="red" x="50" y="50" width="100" height="100"&gt; 
    &lt;view bgcolor="yellow" x="50" y="50" width="60" height="105"/&gt; 
  &lt;/view&gt; 
&lt;/canvas&gt; </example>

<p>Running the example above also shows that the width and height of a view can be different than the dimensions of the bounding box of its child views. No clipping occurred on the "yellow" view even though it lies outside the boundary of its parent.</p>

<p>
If no width and height are actually defined for a view, then it will adopt the width and height of the bounding box not its subviews. If clipping is desired, however, then the attribute <code>clip="true"</code>
can be added to the parent, which would look like the following.</p>

<example title="clipping">
&lt;canvas height="200"&gt;
  &lt;view bgcolor="red" x="50" y="50" width="100" height="100" <em>clip="true"</em>&gt; 
    &lt;view bgcolor="yellow" x="50" y="50" width="60" height="105"/&gt; 
  &lt;/view&gt; 
&lt;/canvas&gt; </example>

<h4>Images and other resources</h4>

<p>
In addition to showing text and color, views are used to display, or play, media files of various formats, such as .gif, .jpeg, .png, .swf, and .mp3, for example. These resources may be compiled into the application or brought in at run time; they can be on the LPS server or on a remote back end, and can be referenced by relative paths or absolute ids. </p>


<h3 id="program-development.data-binding">Data Binding</h3>

<p>
LZX derives much of its power from its unique implementation of data binding, in which the contents of a view are determined by the contents of a dataset. A dataset is simply a named hierarchy of XML data that has a single root node. All data in LZX applications is contained in datasets.</p>
<p>
The concept of data binding implies more than the use of views to display XML data; rather the data itself can determine the size, color, contents, placement, etc. of views, and even cause views to be created or destroyed.  
</p>

<p>Consider the following program:</p>

<example title="simple databinding">
&lt;canvas height="100"&gt; 
  &lt;dataset name="ds"&gt; 
    &lt;record x="10" y="20" name="first" color="332136432"/&gt; 
    &lt;record x="5" y="5" name="second" color="56521236432"/&gt; 
    &lt;record x="20" y="2" name="third" color="1565336432"/&gt; 
  &lt;/dataset&gt; 
  &lt;simplelayout axis="y"/&gt;
  <em>&lt;view datapath="ds:/record"&gt;</em> <!--co>This one line causes three views to be created.</co-->
    &lt;text datapath="@name" bgcolor="$path{'@color'}" x="$path{'@x'}"/&gt; <!--co>
    The <code>$path{}</code> attributes in this line cause each view's textual content, background color, and <attribute>x</attribute> position to be determined by the contents of the dataset</co-->
  &lt;/view&gt; 
&lt;/canvas&gt; </example>

<p>
In the above example, the one line</p>

<pre>
&lt;view datapath="ds:/record"&gt; 
</pre>

<p>Causes three views to be created, and the line</p>

<pre>
&lt;text datapath="@name" bgcolor="$path{@color}" x="$path{@x}"/&gt;
</pre>

<p>causes each view's textual content, background color and
<attribute>x</attribute> position to be determined by the contents of
the dataset.</p>


<h3 id="program-development.libraries-and-includes">Includes and libraries</h3>

<p>
The source code for an LZX application can be contained in a single file; such files can grow quite large and thus hard to manipulate and maintain. By dividing your application into a number of smaller files, however, you can increase maintainability and understandability of your application.   You can even break deep view hierarchies into multiple files to improve modularity, clarity, and source code organization.</p>

<h4>The <tagname>include</tagname> tag</h4>

<p>This tag allows you to specify the name of a file to be include at
any point in your application. The file to be included can be a
library, a view, or text.</p>

<p>When the target is a library file (an XML file whose root element
is <tagname>library</tagname>), the contents of the library file are
included in the application. Any views, scripts, fonts, resources,
audios, datasources, datasets, class definitions, etc. in the library
file are included in the application. A library file can include other
libraries, but a library is included in an application only once, no
matter how many <tagname>include</tagname> statements reference
it. For example,</p>

<example title="app.lzx" executable="false">
&lt;canvas&gt; 
  &lt;include href="library.lzx"/&gt; 
  &lt;mywindow/&gt; 
&lt;/canvas&gt; 
</example>

<example title="library.lzx" executable="false">
&lt;library&gt; 
  &lt;class name="mywindow" extends"window" 
         title="My Title"&gt; 
    &lt;button&gt; Click me! &lt;/button&gt; 
  &lt;/class&gt; 
&lt;/library&gt; 
</example>
<p>
The semantics for including views and text are analogous but slightly different.  Unlike including a library file, a non text or view file is inserted once each time it's included. 
</p>

<h3 id="program-development.comments">Comments</h3>

<h4>XML comments</h4>

<p>These take the form</p>

<code>&lt;!--  comment --&gt;</code>

<p>
and may appear between (but not within) tags in XML text. XML does not have a separate syntax for line ending comments, and does not allow nested comments.</p>
<p>
Often when debugging you find yourself commenting out sections of code. Because it's illegal to nest XML comments within XML comments, this technique does not work for commented sections of declarative LZX. A good way around this problem is to use XML processing instructions which are of the form</p>

<pre>
&lt;?ignore

?&gt;
</pre>

<p>So, to comment out the blue and green views below,</p>

<example title="Commenting out code">
&lt;canvas height="100"&gt;
  &lt;simplelayout/&gt; 
  &lt;!-- This is a red view --&gt; 
  &lt;view bgcolor="red" width="100" height="20"/&gt; 
  &lt;?ignore <co><p>Lines between <code>&lt;?ignore</code> and <code>?&gt;</code> are ignored</p></co>
  &lt;!-- This is a blue view --&gt; 
  &lt;view bgcolor="blue" width="100" height="20"/&gt; 
  &lt;!-- This is a green view --&gt; 
  &lt;view bgcolor="green" width="100" height="20"/&gt; 
  ?&gt;       <co><p>End of the <d:wordasword>ignore</d:wordasword> section</p></co>
  &lt;!-- This is a yellow view --&gt; 
  &lt;view bgcolor="yellow" width="100" height="20"/&gt; 
&lt;/canvas&gt;  
</example>


<h4>Script comments</h4>

<p>
In script, block comments are of the form</p>

<pre>/* comment */</pre>

<p>Line ending comments start with <code>//</code> and continue to the end of the line:</p>

<pre>// line comment</pre>

<pre>
&lt;script&gt; 
  /* script comments look like this */ 
  some.method() // this is an example of comment syntax 
  &lt;!-- ERROR!  do not enclose XML comments in script! --&gt; 
&lt;/script&gt;  // ERROR! Do not include script comments in XML!</pre>


<h3 id="program-development.debugging">Debugging</h3>

<p>The Laszlo system includes an interactive debugger that can be compiled into any application. The debugger displays run time errors, and can be used interactively to inspect and set any tag attributes or JavaScript fields.</p>

<p>You can also use the JavaScript <method>Debug.write</method> method
to cause messages to be displayed in the debugger pane. For
example,</p>

<example title="using the debugger to write messages">
&lt;canvas height="200" debug="true"&gt; 
  &lt;script&gt; 
    Debug.write("Well now how about that!") 
  &lt;/script&gt; 
&lt;/canvas&gt; 
</example>

<p>
To invoke the debugger, set the attribute <code>debug="true"</code>
in the <tagname>canvas</tagname> tag. You can modify the appearance and position of the <tagname>debug</tagname> tag. Note, however, that this tag does not invoke the debugger.</p>
<p>
To use the debugger interactively to inspect a value, you type an expression in to the evaluation pane. For example,</p>

<example title="setting attributes with the debugger">
&lt;canvas height="200" bgcolor="red" debug="true"&gt; 
  &lt;debug y="60"/&gt; 
  &lt;view name="sam" bgcolor="blue" height="50" width="50"/&gt; 
&lt;/canvas&gt; 
</example>
<p>
In the evaluation pane, type,</p>

<code>sam.setAttribute('x', 50)</code>

<p>and press return. The view named <varname>sam</varname> (the blue
square) now appears fifty pixels to the right. </p>

<p>See <xref linkend="debugging"/> for a full discussion of the debugger.</p>

<h4>The Laszlo code viewer</h4>

<p>The Laszlo Presentation Server contains a code viewer that you can
use to inspect any XML file in the lps directory, including, of
course, .lzx sources.  When used to read .lzx files, the viewer
displays syntactically-colored sources, as well as a list of
cross-references such as classes, libraries and art assets.  To invoke
the veiwer, in a browser window enter the URL to <code>/lps-@VERSIONID@/lps/utils/viewer/viewer.jsp</code> and
supply the name of the file you want to view as a <code>file=</code> request type, for example:</p>

<code>
http://localhost:8080/lps-@VERSIONID@/lps/utils/lps/viewer.jsp?file=/my-apps/copy-of-hello.lzx
</code>

<fixme>Say something about running various LPS's at the same time during development?  Also, about cache clearing?
BEWARE: foo.lzx?lzt=clearcache doesn't delete all the cached files if
you're switching back and forth between lps and lps-krank and using
'lps' as the webapp name for both. Make sure to 'env
<?ignore
LPS_HOME=<branch_dir> 
?> ant make reinstall' whenever you do as it will use
the ant task to clear out the cache. I just got bitten by this issue.

See also Eric's notes on same (jrs notebook).
</fixme>
</body>
</html>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2001-2004 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
